﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace CRMTraceTool
{
    public partial class MainForm : Form
    {
        static TraceFile traceFileInfo;
        TraceSearch tSearch = new TraceSearch();
        public string Info { get; set; }
        public List<string> userID { get; set; }
        public string selectedUser { get; set; }
        private List<TraceRecord> currentTraceRecords = new List<TraceRecord>();

        private delegate void populateDataGridViewDelegte(List<TraceRecord> tRecord);

        public MainForm()
        {
            selectedUser = String.Empty;
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
            clearLabels();
            populateSearchColumnDropDown();
        }

        private void populateSearchColumnDropDown()
        {
            columnListBox.Items.Clear();
            operatorBox.Items.Clear();
            messageOrGirdComboBox.Items.Clear();

            columnListBox.Items.Add("RowId");
            columnListBox.Items.Add("RecordTime");
            columnListBox.Items.Add("Process");
            columnListBox.Items.Add("Orgnization");
            columnListBox.Items.Add("Thread");
            columnListBox.Items.Add("Category");
            columnListBox.Items.Add("User");
            columnListBox.Items.Add("Level");
            columnListBox.Items.Add("ReqID");
            columnListBox.Items.Add("Info");
            columnListBox.Items.Add("CallStack");
            columnListBox.Items.Add("Message");

            operatorBox.Items.Add("=");
            operatorBox.Items.Add("Contains");

            messageOrGirdComboBox.Items.Add("Export users ID's and Org ID's from Message");
            messageOrGirdComboBox.Items.Add("Export users ID's and Org ID's from Grid");
            messageOrGirdComboBox.Items.Add("Export users ID's and Org ID's from Both");
        }

        private void exitApp_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void openLogFileMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openLogFileDialog = new OpenFileDialog();

            StringBuilder traceFileBuilder = new StringBuilder();
            string testString = String.Empty;

            try
            {
                if (openLogFileDialog.ShowDialog() == DialogResult.OK)
                {
                    this.Text = "CRM Trace Tool" + " - " + openLogFileDialog.SafeFileName;
                    dataGridView1.DataBindings.Clear();
                    traceFileInfo = new TraceFile();
                    traceFileInfo = evalString(openLogFileDialog.OpenFile());
                    populateLabels();
                }
            }
            catch (IOException IOex)
            {
                MessageBox.Show("An error has occured, error message is:\n\n" + IOex.Message, Application.ProductName + " IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error has occured, error message is:\n\n" + ex.Message, Application.ProductName + " Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
            }
        }

        private void populateLabels()
        {
            traceVersionLable.Text = traceFileInfo.CRMVersion;
            labelCallStackOn.Text = traceFileInfo.CallStackOn;
            labelCategories.Text = traceFileInfo.Categories;
            tbComputerName.Text = traceFileInfo.ComputerName;
            labelDeploymentType.Text = traceFileInfo.DeploymentType;
            labelLocalTime.Text = traceFileInfo.LocalTime;
            labelScaleGroup.Text = traceFileInfo.ScaleGroup;
            labelServerRole.Text = traceFileInfo.ServerRole;
            labelCRMVersion.Text = traceFileInfo.CRMVersion;

            populateDataGridView(traceFileInfo.traceRecords);

            exportButton.Enabled = false;
            clearSearch.Enabled = false;
            findButton.Enabled = false;
            contextMenu.Enabled = true;

            enableDisableButtons();
        }

        private void clearLabels()
        {
            traceVersionLable.Text = String.Empty;
            labelCallStackOn.Text = String.Empty;
            labelCategories.Text = String.Empty;
            labelDeploymentType.Text = String.Empty;
            labelLocalTime.Text = String.Empty;
            labelScaleGroup.Text = String.Empty;
            labelServerRole.Text = String.Empty;
            labelCRMVersion.Text = String.Empty;
        }



        private void populateDataGridView(List<TraceRecord> tRecords)
        {
            Cursor.Current = Cursors.WaitCursor;

            if (tRecords.Count >= 1)
            {
                if (dataGridView1.InvokeRequired)
                {
                    dataGridView1.Invoke(new populateDataGridViewDelegte(this.populateDataGridView), tRecords);
                }
                else
                {
                    dataGridView1.DataSource = tRecords;
                }
                currentTraceRecords = tRecords;
                PopulateTextboxes(0);
                labelTimeSpent.Text = "Time Taken:  " + tSearch.calculateTimeSpent(tRecords[0].RecordTime, tRecords[tRecords.Count - 1].RecordTime);
                rowsFound.Text = "Rows Found:  " + tRecords.Count.ToString();
            }
            else
            {
                dataGridView1.DataSource = null;
                labelTimeSpent.Text = "Time Taken: ";
                rowsFound.Text = "Rows Found:  ";
                exportButton.Enabled = false;
                findButton.Enabled = false;
                contextMenu.Enabled = false;
            }

            Cursor.Current = Cursors.Default;
        }

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            int currentRow = dataGridView1.CurrentRow.Index;
            if (dataGridView1.Rows.Count >= 1)
            {
                PopulateTextboxes(currentRow);
            }
        }

        private void PopulateTextboxes(int currentRow)
        {
            string callStack = String.Empty;
            string message = String.Empty;

            if (dataGridView1.Rows.Count >= 1 && dataGridView1.Columns.Contains("CallStack"))
            {
                callStack = dataGridView1.Rows[currentRow].Cells["CallStack"].Value == null ? String.Empty : dataGridView1.Rows[currentRow].Cells["CallStack"].Value.ToString();
                message = dataGridView1.Rows[currentRow].Cells["Message"].Value == null ? String.Empty : dataGridView1.Rows[currentRow].Cells["Message"].Value.ToString();

                if (removeHTTPCodes.Checked)
                {
                    message = tSearch.ParseText(message);
                }

                tbCallStack.Text = callStack;
                tbMessageBox.Text = message;
            }
            else
            {
                tbCallStack.Text = String.Empty;
                tbMessageBox.Text = String.Empty;
            }
        }

        private void clearSearch_Click(object sender, EventArgs e)
        {
            reqIDtoFind.Text = String.Empty;
            populateLabels();
        }

        private void messageWordWrap_CheckedChanged(object sender, EventArgs e)
        {
            tbMessageBox.WordWrap = messageWordWrap.Checked;
            PopulateTextboxes(dataGridView1.CurrentRow.Index);
        }

        private void callStackWordWrap_CheckedChanged(object sender, EventArgs e)
        {
            tbCallStack.WordWrap = callStackWordWrap.Checked;
            PopulateTextboxes(dataGridView1.CurrentRow.Index);
        }

        private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            if (traceFileInfo.Categories == "*:Error")
                return;

            changeRowColor(e);
            enableColumnSorting();
        }

        private void enableColumnSorting()
        {
            foreach (DataGridViewColumn col in dataGridView1.Columns)
            {
                col.SortMode = DataGridViewColumnSortMode.Programmatic;
            }
        }

        private void changeRowColor(DataGridViewBindingCompleteEventArgs e)
        {
            DataGridViewCellStyle red = dataGridView1.DefaultCellStyle.Clone();
            red.BackColor = Color.Red;

            DataGridViewCellStyle yellow = dataGridView1.DefaultCellStyle.Clone();
            yellow.BackColor = Color.Yellow;

            if (e.ListChangedType != ListChangedType.ItemDeleted)
            {
                foreach (DataGridViewRow r in dataGridView1.Rows)
                {
                    if (r.Cells.Count > 7)
                    {
                        try
                        {
                            //Error
                            if (r.Cells["Level"].Value.ToString().Contains("Error"))
                            {
                                r.DefaultCellStyle = red;
                            }
                            //Warning
                            if (r.Cells["Level"].Value.ToString().Contains("Warning"))
                            {
                                r.DefaultCellStyle = yellow;
                            }
                        }
                        catch (NullReferenceException nullEx)
                        {
                            MessageBox.Show("There is an issue with the format of trace file.  The following error was generated " + "\"" + nullEx.Message + "\"", "Trace File Format Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }

                    }
                }
            }
        }

        public void highlightUsers(string user)
        {
            changeCellColor(user);
        }

        private void changeCellColor(string user)
        {
            DataGridViewCellStyle blue = new DataGridViewCellStyle();
            blue.BackColor = Color.LightBlue;

            DataGridViewCellStyle white = new DataGridViewCellStyle();
            white.BackColor = Color.White;

            selectedUser = user;

            foreach (DataGridViewRow r in dataGridView1.Rows)
            {
                if (r.Cells["User"].Style.BackColor == blue.BackColor)
                {
                    r.Cells["User"].Style = white;
                }
            }

            if (!String.IsNullOrEmpty(user))
            {
                foreach (DataGridViewRow r in dataGridView1.Rows)
                {
                    if (r.Cells["User"].Value.ToString().Contains(user))
                    {
                        r.Cells["User"].Style = blue;
                    }
                }
            }
        }

        public void updateColor(string fromForm2)
        {
            tbComputerName.Text = fromForm2;
        }

        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            List<TraceRecord> traceRecord = new List<TraceRecord>();
            traceRecord = tSearch.SortColumn(traceFileInfo, dataGridView1.Columns[e.ColumnIndex].Name, dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection.ToString());
            dataGridView1.DataSource = null;
            dataGridView1.DataSource = traceRecord;
            dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
        }

        private void findButton_Click(object sender, EventArgs e)
        {
            if (columnListBox.SelectedItem.ToString() == "RowId")
            {
                try
                {
                    Convert.ToInt32(searchItemBox.Text);
                }
                catch
                {
                    MessageBox.Show("Only integers are allowed to search RowId", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    searchItemBox.Text = String.Empty;
                    return;
                }
            }

            populateDataGridView(tSearch.queryTraceRecords(traceFileInfo, columnListBox.SelectedItem.ToString(), operatorBox.SelectedItem.ToString(), searchItemBox.Text));
            clearSearch.Enabled = true;
        }

        private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
                {
                    dataGridView1.CurrentCell = dataGridView1[e.ColumnIndex, e.RowIndex];

                    switch (dataGridView1.CurrentCell.OwningColumn.HeaderText)
                    {
                        case "CallStack":
                        case "Message":
                            findAllToolStripMenuItem.Enabled = false;
                            findAllToolStripMenuItem.Text = "Use search box to search " + dataGridView1.CurrentCell.OwningColumn.HeaderText;
                            break;
                        default:
                            findAllToolStripMenuItem.Enabled = true;
                            findAllToolStripMenuItem.Text = "Find All.... " + dataGridView1.CurrentCell.Value.ToString();
                            break;
                    }
                }
            }
        }

        private void findAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            for (int x = 0; x < columnListBox.Items.Count; x++)
            {
                if (columnListBox.Items[x].ToString() == dataGridView1.CurrentCell.OwningColumn.HeaderText)
                {
                    columnListBox.SelectedIndex = x;
                    break;
                }
            }

            for (int x = 0; x < operatorBox.Items.Count; x++)
            {
                if (operatorBox.Items[x].ToString() == "=")
                {
                    operatorBox.SelectedIndex = x;
                }
            }

            searchItemBox.Text = dataGridView1.CurrentCell.Value.ToString();

            populateDataGridView(tSearch.queryTraceRecords(traceFileInfo, dataGridView1.CurrentCell.OwningColumn.HeaderText, "=", dataGridView1.CurrentCell.Value.ToString()));
            clearSearch.Enabled = true;
        }

        private void exportButton_Click(object sender, EventArgs e)
        {
            switch (messageOrGirdComboBox.SelectedItem.ToString())
            {
                case "Export users ID's and Org ID's from Message":
                    sendToCSVFile(generateUserListCSVFile(tSearch.ExtractUsersFromMessage(currentTraceRecords)));
                    break;
                case "Export users ID's and Org ID's from Grid":
                    sendToCSVFile(generateUserListCSVFile(tSearch.ExtractUsersFromColumns(currentTraceRecords)));
                    break;
                case "Export users ID's and Org ID's from Both":
                    sendToCSVFile(generateUserListCSVFile(tSearch.ExtractUsersFromColumnAndMessages(currentTraceRecords)));
                    break;
                case "Export rows to CSV":
                    sendToCSVFile(tSearch.generateCSV(currentTraceRecords));
                    break;
            }
        }

        private StringBuilder generateUserListCSVFile(List<users> listOfUser)
        {
            StringBuilder sb = new StringBuilder();

            if (listOfUser.Count > 1)
            {
                sb.Append("UserID,OrganizationId");
                sb.AppendLine();

                foreach (users u in listOfUser)
                {
                    sb.Append(u.userId);
                    sb.Append(",");
                    sb.Append(u.orgId);
                    sb.AppendLine();
                }
            }
            else
            {
                sb.Append("Users could not be extracted from the trace file");
            }

            return sb;
        }

        private void sendToCSVFile(StringBuilder sb)
        {
            string path = String.Empty; Directory.GetCurrentDirectory();

            SaveFileDialog saveFile = new SaveFileDialog();

            try
            {
                saveFile.InitialDirectory = Directory.GetCurrentDirectory();
                saveFile.Title = "Save Export";
                saveFile.CheckFileExists = false;
                saveFile.CheckPathExists = true;
                saveFile.DefaultExt = "csv";
                saveFile.Filter = "CSV Files (*.csv)|*.csv|All files (*.*)|*.*";
                saveFile.FilterIndex = 2;
                saveFile.RestoreDirectory = true;
                saveFile.FileName = this.Text.Replace("CRM Trace Tool - ", "") + ".csv";

                if (saveFile.ShowDialog() == DialogResult.OK)
                {
                    System.IO.File.WriteAllText(saveFile.FileName, sb.ToString());
                    MessageBox.Show("File has been saved.");
                }
            }
            catch (UnauthorizedAccessException UAEx)
            {
                MessageBox.Show("You are not authorized to access the folder", "Folder access error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            catch (PathTooLongException PathEx)
            {
                MessageBox.Show("The path is tool long, select a different location", "Path too long error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            catch (IOException IOex)
            {
                MessageBox.Show("An error has occured, error message is:\n\n" + IOex.Message, Application.ProductName + " IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
            }
        }

        private void aboutCRMTraceToolToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutUsForm aboutUsForm = new AboutUsForm();

            aboutUsForm.ShowDialog();
        }

        private void removeHTTPCodes_CheckedChanged(object sender, EventArgs e)
        {
            PopulateTextboxes(dataGridView1.CurrentRow.Index);
        }

        private void columnListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (columnListBox.SelectedItem.ToString() == "RowId")
            {
                for (int x = 0; x < operatorBox.Items.Count; x++)
                {
                    if (operatorBox.Items[0].ToString() == "=")
                    {
                        operatorBox.SelectedIndex = 0;
                    }
                }
            }
            enableDisableButtons();
        }

        private void operatorBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            enableDisableButtons();
        }

        private void searchItemBox_TextChanged(object sender, EventArgs e)
        {
            enableDisableButtons();
        }

        private void enableDisableButtons()
        {
            if (findButton.Enabled)
                return;

            if (columnListBox.SelectedIndex > -1 && operatorBox.SelectedIndex > -1 && String.IsNullOrWhiteSpace(searchItemBox.Text) || searchItemBox.Text.Length > 0 && dataGridView1.RowCount > 0)
                findButton.Enabled = true;
        }

        private void messageOrGirdComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (messageOrGirdComboBox.SelectedIndex > 0 && dataGridView1.RowCount > 0)
                exportButton.Enabled = true;
        }

        private TraceFile evalString(Stream itemToTest)
        {
            int newTraceRow = 0;
            StreamReader logFileStream = null;
            OpenFileDialog openLogFileDialog = new OpenFileDialog();
            TraceFile traceFile = new TraceFile();
            traceFile.traceRecords = new List<TraceRecord>();
            TraceRecord traceRecord = new TraceRecord();

            List<string> tString = new List<string>();

            string testString = String.Empty;
            logFileStream = new StreamReader(itemToTest);
            string stringLength = String.Empty;
            string startofString = String.Empty;

            bool headerPopulated = false;

            bool isCallStack = false;
            StringBuilder callStackInfo = new StringBuilder();

            bool isMessageInfo = false;
            StringBuilder messageInfo = new StringBuilder();

            traceRecord = new TraceRecord();

            Cursor.Current = Cursors.WaitCursor;

            #region Load string list
            try
            {
                using (logFileStream)
                {
                    while (!logFileStream.EndOfStream)
                    {
                        tString.Add(logFileStream.ReadLine());
                    }
                }
            }
            catch (IOException IOex)
            {
                MessageBox.Show("An error has occured, error message is:\n\n" + IOex.Message, Application.ProductName + " IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
            }

            catch (Exception ex)
            {
                throw ex;
            }
            #endregion

            for (int x = 0; x < tString.Count; x++)
            {
                if (headerPopulated)
                {
                    if (tString[x].StartsWith("#"))
                        continue;
                }

                #region Header Population
                if (!headerPopulated && tString[x].StartsWith("#"))
                {
                    if (tString[x].StartsWith("# CRM T"))
                    {
                        stringLength = "# ";
                        traceFile.CRMTracingVersion = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# LocalTime"))
                    {
                        stringLength = "# LocalTime: ";
                        traceFile.LocalTime = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# Categ"))
                    {
                        stringLength = "# Categories: ";
                        traceFile.Categories = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# Sched"))
                    {
                        stringLength = "# Schedule: ";
                        traceFile.Schedule = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# CallS"))
                    {
                        stringLength = "# CallStackOn: ";
                        traceFile.CallStackOn = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# CRMVe"))
                    {
                        stringLength = "# CRMVersion: ";
                        traceFile.CRMVersion = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# Deplo"))
                    {
                        stringLength = "# DeploymentType: ";
                        traceFile.DeploymentType = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# Scale"))
                    {
                        stringLength = "# ScaleGroup: ";
                        traceFile.ScaleGroup = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# Serv"))
                    {
                        stringLength = "# ServerRole: ";
                        traceFile.ServerRole = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                    else if (tString[x].StartsWith("# Comp"))
                    {
                        stringLength = "# ComputerName: ";
                        traceFile.ComputerName = tString[x].Substring(stringLength.Length);
                        continue;
                    }
                }
                #endregion

                headerPopulated = true;

                if (String.IsNullOrEmpty(tString[x]))
                {
                    continue;
                }

                #region StartsWith("[2")
                if (tString[x].StartsWith("[2"))
                {
                    if (traceRecord.RecordTime != null)
                    {
                        if (isCallStack && traceFile.CallStackOn == "Yes")
                        {
                            traceRecord.CallStack = callStackInfo.ToString();
                            callStackInfo.Clear();
                            isCallStack = false;
                        }
                        else
                            traceRecord.CallStack = String.Empty;

                        if (isMessageInfo)
                        {
                            traceRecord.Message = messageInfo.ToString();
                            messageInfo.Clear();
                            isMessageInfo = false;
                        }

                        traceFile.traceRecords.Add(traceRecord);

                        traceRecord = new TraceRecord();
                        newTraceRow++;
                    }

                    string[] newLine = tString[x].Split('|');

                    traceRecord.RowId = newTraceRow;

                    for (int y = 0; y < newLine.Length; y++)
                    {

                        switch (newLine[y].Substring(0, 1))
                        {
                            case "[":
                                stringLength = "2013-09-25 06:11:49.516";
                                traceRecord.RecordTime = newLine[y].Substring(1, stringLength.Length);
                                startofString = "[2013-09-25 06:11:49.516] Process: ";
                                traceRecord.Process = newLine[0].Substring(startofString.Length - 1);
                                break;
                            case "O":
                                startofString = "Organization:";
                                traceRecord.Organization = newLine[y].Substring(startofString.Length).TrimStart(' ').TrimEnd();
                                break;
                            case "T":
                                startofString = "Thread:";
                                traceRecord.Thread = newLine[y].Substring(startofString.Length).TrimStart(' ').TrimEnd();
                                break;
                            case "C":
                                startofString = "Category:";
                                traceRecord.Category = newLine[y].Substring(startofString.Length).TrimStart(' ').TrimEnd();
                                break;
                            case "U":
                                startofString = "User:";
                                traceRecord.User = newLine[y].Substring(startofString.Length).TrimStart(' ').TrimEnd();
                                break;
                            case "L":
                                startofString = "Level:";
                                traceRecord.Level = newLine[y].Substring(startofString.Length).TrimStart(' ').TrimEnd();
                                break;
                            case "R":
                                startofString = "ReqId:";
                                traceRecord.ReqID = newLine[y].Substring(startofString.Length).TrimStart(' ').TrimEnd();
                                break;
                            case " ":
                                traceRecord.Info = newLine[y].TrimStart(' ').TrimEnd();
                                break;
                        }
                    }
                    continue;
                }
                #endregion

                if (traceFile.CallStackOn == "Yes")
                {
                    if (tString[x].StartsWith("\tat"))
                    {

                        isCallStack = true;
                        callStackInfo.Append(tString[x]);
                        callStackInfo.AppendLine();
                        continue;
                    }
                }

                if (tString[x].StartsWith(">") || isMessageInfo)
                {
                    isMessageInfo = true;
                    messageInfo.Append(tString[x]);
                    messageInfo.AppendLine();
                    continue;
                }
            }  //end for 

            if (traceFile.CallStackOn == "No")
            {
                traceRecord.CallStack = String.Empty;
            }
            else
                traceRecord.CallStack = callStackInfo.ToString();

            traceRecord.Message = messageInfo.ToString();
            traceFile.traceRecords.Add(traceRecord);

            Cursor.Current = Cursors.Default;

            return traceFile;
        }
    }
}